package cn.jdemo.base.synchronousqueue;

import cn.jdemo.base.Node;

import java.util.PriorityQueue;
import java.util.Queue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

/**
 * @see cn.willbj.brief.queue 参考
 *
 * <p> 队列
 * @see Queue
 * @see Queue#offer(Object) 添加
 * @see Queue#add(Object) 添加-容量满异常
 * @see Queue#peek() 检索
 * @see Queue#element() 检索-容量空异常
 * @see Queue#poll() 检索并删除
 * @see Queue#remove() 检索并删除-容量空异常
 *
 * <p> (并发阻塞)同步队列: 一个线程添加,另一个线程检出
 * @see java.util.concurrent.SynchronousQueue
 * @see SynchronousQueue#offer(Object) 添加
 * @see SynchronousQueue#offer(Object, long, TimeUnit) 添加-无消费,等待指定时间
 * @see SynchronousQueue#put(Object) 阻塞添加
 * @see SynchronousQueue#poll() 检出
 * @see SynchronousQueue#poll(long, TimeUnit) 检出-无数据,等待指定时间
 * @see SynchronousQueue#take() 阻塞检出
 *
 */
public class App {
    public static void main(String[] args) throws InterruptedException {
        testBase();
        testBase02();
        testBase03();
    }

    public static void testBase() throws InterruptedException {
        SynchronousQueue<Node> queue = new SynchronousQueue<>();
        Node node1 = Node.builder().num(1).build();
        Node node2 = Node.builder().num(2).build();
        Node node3 = Node.builder().num(3).build();
        System.out.println(queue.offer(node1,1000*2, TimeUnit.MILLISECONDS));// false
        System.out.println(queue.offer(node2));// false
        System.out.println(queue.poll());// null
        System.out.println(queue.offer(node3));// false
        System.out.println(queue.poll());// null
    }

    public static void testBase02() throws InterruptedException {
        SynchronousQueue<Node> queue = new SynchronousQueue<>();
        Node node1 = Node.builder().num(1).build();
        Thread thread1 = new Thread(() -> {
            try {
                System.out.println(queue.offer(node1,1000*2, TimeUnit.MILLISECONDS));// true
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        thread1.start();
        Thread thread2 = new Thread(() -> {
            try {
                System.out.println(queue.poll(1000*3, TimeUnit.MILLISECONDS));// Node(num=1, name=null)
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        thread2.start();

    }

    public static void testBase03() throws InterruptedException {
        SynchronousQueue<Node> queue = new SynchronousQueue<>();
        Node node1 = Node.builder().num(1).build();
        Thread thread1 = new Thread(() -> {
            try {
                queue.put(node1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        thread1.start();
        Thread thread2 = new Thread(() -> {
            try {
                System.out.println(queue.take());// Node(num=1, name=null)
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        thread2.start();

    }
}
